package com.vains.utils;

import com.vains.entity.OauthUser;
import com.vains.exception.CustomerException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices;

/**
 * spring boot应用帮助类
 *
 * @author vains
 * @version 1.0
 * @since 2020/8/6 13:02
 **/
@Slf4j
public class SecurityContextUtils {

    private SecurityContextUtils() {}

    /**
     * 从token中获取认证信息
     * @param resourceServerTokenServices DefaultTokenServices
     * @return 返回认证信息
     */
    public static OAuth2Authentication getAuthenticationByToken(ResourceServerTokenServices resourceServerTokenServices) {
        // 从请求中获取token
        String token = SpringContextUtils.getToken();
        log.info("根据token: {} 获取认证信息...", token);
        if (StringUtils.isBlank(token)) {
            // token 不正确处理
            log.warn("token 为空, 获取认证信息失败");
            throw new CustomerException("token 为空, 获取认证信息失败");
        }
        OAuth2AccessToken accessToken = resourceServerTokenServices.readAccessToken(token);
        if (accessToken == null) {
            // token不正确
            log.warn("token 不正确, 获取认证信息失败");
            throw new CustomerException("token 不正确, 获取认证信息失败");
        } else if (accessToken.isExpired()) {
            // token 已过期
            log.warn("token 已过期, 获取认证信息失败");
            throw new CustomerException("token 已经过期, 请重新获取!");
        }
        log.info("根据 token 获取认证信息成功!");
        return resourceServerTokenServices.loadAuthentication(accessToken.getValue());
    }

    /**
     * 获取当前用户的详细信息
     * @return 当前用户
     */
    public static OauthUser getCurrentUser(ResourceServerTokenServices resourceServerTokenServices) {
        OAuth2Authentication authentication = getAuthenticationByToken(resourceServerTokenServices);
        log.info("开始根据token获取的认证信息来获取当前用户信息");
        if (authentication == null) {
            // 获取当前用户信息失败
            log.warn("获取当前用户信息失败, 认证信息为空");
            return null;
        }
        log.info("当前用户信息获取成功!");
        return (OauthUser) authentication.getPrincipal();
    }

}
